package com.tom.architect02.mnbase.annotation.jvms.jssit
//
//import com.android.build.api.transform.Format
//import com.android.build.api.transform.QualifiedContent
//import com.android.build.api.transform.Transform
//import com.android.build.api.transform.TransformException
//import com.android.build.api.transform.TransformInvocation
//import com.android.build.gradle.internal.pipeline.TransformManager
//import javassist.ClassPool
//import javassist.CtClass
//import javassist.CtMethod
//import org.apache.commons.io.FileUtils
//import org.gradle.api.Project;

// 编译时的环节。输出到classes.dex
//public class ModifyTransform extends Transform {
//    def project // 定义变量，可以用来查找类。
////    内存在哪里【1】：   window   1  android 2
//    def pool = ClassPool.default // 字节码池。
//// project用来查找类
//    ModifyTransform(Project project) {
//        this.project = project
//    }
//
//    @Override  // 连接输入和输出。TODO 重点方法。
//    void transform(TransformInvocation transformInvocation) throws TransformException, InterruptedException, IOException {
//        super.transform(transformInvocation)
//        project.android.bootClasspath.each {
//            pool.appendClassPath(it.absolutePath) // class文件添加 入字节码池。
//        }
////       1. 拿到输入，遍历所有输入。
//        transformInvocation.inputs.each {
////            class 依赖文件夹---> 文件夹
//            it.directoryInputs.each { // 1.1 处理文件夹
//                def preFileName =    it.file.absolutePath
//                pool.insertClassPath(preFileName) // 加进内存
//                println "========directoryInputs======== " + preFileName
//                findTarget(it.file, preFileName)
////  it.file
//                // 2. 查询输出的文件夹 （目的地），通过provider去定位。
//                def dest = transformInvocation.outputProvider.getContentLocation(
//                        it.name,
//                        it.contentTypes,
//                        it.scopes,
//                        Format.DIRECTORY
//                )
//                // 3. 文件copy  ---》 复制到下一个环节 dest
//                FileUtils.copyDirectory(it.file, dest)
//            }
//            it.jarInputs.each { // 1.2 遍历处理jar包(包含系统的jar包)
//                    def dest = transformInvocation.outputProvider.getContentLocation(it.name
//                            , it.contentTypes, it.scopes, Format.JAR)
////                    去哪里
//                    FileUtils.copyFile(it.file, dest)
//            }
////            目的：修改class   不是修改 jar
//        }
//
////       2 查询输出的文件夹    目的地
////       3  文件copy  ---》 下一个环节
////        想干嘛干嘛
//    }
//
////    寻找目标class
////    fileName C:\Users\maniu\Downloads\ManiuJavaSsit\app\build\intermediates\javac\debug\classes  待copy的路径。
//    private void findTarget(File dir, String fileName) {
//        if (dir.isDirectory()) { // 是文件夹，再次递归，搜寻.class。
//            dir.listFiles().each { // 子文件递归查找
//                findTarget(it, fileName)
//            }
//        } else {
//            def filePath = dir.absolutePath
//            if (filePath.endsWith(".class")) {
//                // 修改文件
//                modify(filePath, fileName)
//            }
//        }
//    }
//    private void modify(def filePath, String fileName) { // 修改文件
//        if (filePath.contains('R$') || filePath.contains('R.class')
//                || filePath.contains("BuildConfig.class")) {
//            return   // 过滤R文件（系统文件），不处理
//        }
//
//// 基于javassit  ----》先拿到全类名(\com\maniu\javassit\MainActivity.class)--> com.maniu.javassit.MainActivity
//        def className =  filePath.replace(fileName, "").replace("\\", ".")  .replace("/", ".") // .com.maniu.javassit.MainActivity.class
//        def name = className.replace(".class", "").substring(1) // com.maniu.javassit.MainActivity
//        println "========name======== " + name
////      类似：  修改json 文件   ----》 javabean-- 修改---》 fastjson ----》回写到 json文件中。
//        CtClass ctClass=  pool.get(name) //根据包名，从字节码池 池子里面取    CtClass开始用到javassist。
//        addCode(ctClass, fileName) // 修改ctClass
//    }


//    private void addCode(CtClass ctClass ,String fileName) {
////        捡出来，要使用到ctClass
//        ctClass.defrost()
//        CtMethod[] methods = ctClass.getDeclaredMethods() // 通过反射拿到所有方法
//        for (method in methods) { // 遍历每个方法，修改。
//
//            println "method "+method.getName()+"参数个数  " + method.getParameterTypes().length
//            method.insertAfter("if(true){}") // 在每个方法最后面添加代码。 insertAfter
//            if (method.getParameterTypes().length == 1) { // 参数个数1.
//                method.insertBefore("{ System.out.println(\$1);}") // 在方法前面插入代码。打印所有输入参数
//            }
//            if (method.getParameterTypes().length == 2) {
//                method.insertBefore("{ System.out.println(\$1); System.out.println(\$2);}")
//            }
//            if (method.getParameterTypes().length == 3) {
//                method.insertBefore("{ System.out.println(\$1);System.out.println(\$2);System.out.println(\\\$3);}")
//            }
//        }
//        ctClass.writeFile(fileName) // 回写文件进去
//        ctClass.detach() // 解绑内存
//    }

//    @Override
//    String getName() {
//        return "david" // 文件夹名字(工作台)，在app/build/intermediates/transforms中生成david文件夹。
//    }
//    @Override
//    Set<QualifiedContent.ContentType> getInputTypes() {
//        return TransformManager.CONTENT_CLASS // 输入类型
//    }
//    @Override
//    Set<? super QualifiedContent.Scope> getScopes() {
//        return TransformManager.SCOPE_FULL_PROJECT // 类型
//    }
//    @Override
//    boolean isIncremental() {
//        return false // 增量更新
//    }
//}


//反编译工具jadx-gui
//javassist: 给.class文件 中的方法 添加代码。

